/*
 * Stack.c
 *
 *  Created on: 2011-5-23
 *      Author: william nie
 */

#include"Stack.h"

Status InitStack(Stack **stack, int initSize) {
	(*stack) = (Stack*) malloc(sizeof(Stack));
	(*stack)->top = (*stack)->base = (SNode*) malloc(initSize * sizeof(SNode));
	if ((*stack)->base == NULL) {
		fprintf(stderr, "ERROR WHEN INITIALIZE STACK.");
		fflush(stdin);
		getchar();
		exit(1);
	}
	(*stack)->length = 0;
	(*stack)->size = initSize * sizeof(SNode);

	return OK;
}

Status DestroyStack(Stack **stack) {
	free((*stack)->base);
	free(*stack);
	(*stack) = NULL;

	return OK;
}

Status ClearStack(Stack *stack) {
	stack->top = stack->base;
	stack->length = 0;

	return OK;
}

BOOL StackEmpty(Stack *stack) {
	if (stack->length == 0) {
		return TRUE;
	}
	return FALSE;
}

int StackLength(Stack *stack) {
	return stack->length;
}

SNode* GetTop(Stack *stack) {
	if (stack->top == stack->base) {
		return NULL;
	}
	return stack->top - 1;
}

Status Push(Stack *stack, SElemType *elem) {
	if (stack->top - stack->base >= stack->size) {
		stack->base = (SNode*) realloc(stack->base, (stack->size
				+ STACK_INCREMENT) * sizeof(SNode));
		if (stack->base == NULL) {
			fprintf(stderr, "ERROR WHEN REALLOC FOR STACK.");
			fflush(stdin);
			getchar();
			exit(1);
		}
		stack->top = stack->base + stack->size;
		stack->size += STACK_INCREMENT;
	}

	stack->top->data = elem;
	stack->top++;
	return OK;
}

SElemType* Pop(Stack *stack) {
	if (stack->top == stack->base) {
		return NULL;
	}

	return (--stack->top)->data;
}

Status StackTraverse(Stack *stack, StackVisit visit) {
	if (stack->base == stack->top) {
		printf("Stack Is Empty.");
		return OK;
	}
	SNode *base = stack->base;

	while (base != stack->top) {
		if (visit(base) == FALSE) {
			return ERROR;
		}
		base++;
	}

	return OK;
}

/*****Nonstandard Functions*****/

Status FillStack(Stack *stack) {
	printf("Fill The Stack With Integer Value.\n");

	SElemType *data = (SElemType*)malloc(sizeof(SElemType));

	while(scanf("%d",data)){
		Push(stack,data);
		data = (SElemType*)malloc(sizeof(SElemType));
	}

	printf("Fill Stack Complete.\n\n");

	return OK;
}

BOOL DefaultStackVisit(SNode *sNode){
	printf("%d ",*(sNode->data));
	return TRUE;
}
